1. Assignment 1: Simple Counter¶
The goal of this first assignment is to get familiar with writing a testbench for a very simple module, and start the simulation.
We will write a very simple counter first, then enhance it with a few features, and improve the testbench along the way.
The goal of this assignment is to get used to:
- Writing code
- Quick check the syntax with the simulator
- Prepare a test bench
- Improve the design incrementally and quickly rerun the tools
Tip
The tutorials about the tools are located in the Tools and Languages sections, go back to them whenever you forgot how a tool works.
Tip
The Verilog Syntax and features is explained in the lecture part Verilog Hardware Description Language , we will refer to it when necessary.
Tip
The assignments descriptions don’t show much code, but refer to the tutorials and lecture where you can find examples.
1.1. Cadence Tools¶
First you should read about the Cadence Tools and the Tool Irun, to learn how to start the tool.
1.2. Organising your work Folder¶
To work on the assignments, you should create a folder for DDS, called for example “dds17”, and create a sub folder per assignment.
If you have never used a Linux command Line, you can look at the Linux tutorial.
For this assignment, the folder structure could look like:
- dds17/
- assignment1/
1.3. Assignments Plan¶
The assigment plan for the Lab work is not fixed.
If you are slower or faster than the time table it is not really important, you should just focus on learning how to design the circuit, simulate it and implement it.
1.4. First Version¶
1.4.1. Specification¶
To start off, we will create an 8 bit Counter that simply increments its value upon a clock positive edge.
As we have seen in the lecture, a System is usually represented by a drawing of a Box with input and outputs drawn as arrows:

This picture means, we will declare a Module called “counter” with:
- One input called “clk”
- One output called “value”, with a size of 8 bits
- The value must be a register , because the value is incremented and updated at a clock cycle edge
- The clock is the input “clk”
Hint
Create a file called “counter.v” , and create a Module with Input/Outputs for the counter
Hint
Look at the Lecture to see how to code in Verilog, don’t hesitate to copy-paste and rename
Hint
Don’t implement to counting part right now, we will first check if the code is correct.
1.4.2. Simulation: Syntax Check¶
So far we should have written a very few lines of code, but we want to check right away that no syntax error are present, like:
- Missing “,” or “;”
- Unbalanced parenthesis
- Extra “,” at the end of a list etc…
To do that, we will start cadence-irun on the file “counter.v”.
The command should look like:
~/dds17/assignment1 $ irun counter.v
Or if you are using a command file:
~/dds17/assignment1 $ irun -f counter.f
Hint
Look at the cadence-irun reference to learn about irun.
Hint
If your design is error free, you can continue
1.4.3. Simulation: Create a testbench¶
Tip
Look at the Lecture Simulation Testbench to learn how to code the elements of this section
We have briefly introduced in the lecture that a Simulation is a piece of software which drives the inputs of the tested design.
To begin with the testbench, you need to write down which inputs are to be driven and how.
Question
Which input does the test bench need to drive to simulate our simple counter?
To create the testbench, open a new file which you can call “counter_tb.v”, and prepare a Verilog Module called “counter_tb”.
Hint
the suffix “_tb” in the file name and module name is a widely used way to name test bench modules and files to ease readiness.
Once you have created the testbench module, you need to add:
- A Module Instance of the counter.
- A clock register which the testbench software will drive.
- A clock generator.
Start the simulation using irun passing both files as input, and with the Graphical Environment Simvision:
~/dds17/assignment1 $ irun -gui -access +rw counter.v counter_tb.v
Question
Can you see the Testbench and Counter hierarchy in the design browser
Question
Start the simulation in a Waveform window, can you see the clock running?
1.4.4. Implementation: Counting¶
So far we have passed the first step to implement the design:
- Create the Module, it’s input and outputs, and the Testbench Hierarchy
- Define and generate a clock to drive the design
This order of design should be the same as we have have presentend during the lecture.
Now we would like the counter to actually count, so we will have to implement the circuit. To do so, we will need:
- A Pipeline Stage reacting to the positive edge of the clock
- An assignment to update the counter value output.
Go back to the “counter.v” file, and add the code.
Tip
Pipeline stages are described in the lecture
Todo
Reinvoke the simulator (see irun tutorial) and run the simulation, add the value output of the counter to the waveform.
Question
What do you see in the waveform? can you see a value counting?
1.4.5. Implementation: Reset¶
If everything works as expected, you should not see the value increment, but instead a constant red X.
The X value means “undefined”, as shortly described in the lecture.
The simulator will never update an undefined value, because it does not know how to start.
Theoretically, in real life, the counter would have some value and count from there. However, most signals in a design need a defined state.
Todo
Add a Reset Block to the pipeline stage, and an output. Set the counter value initially to 0.

Todo
Add a Reset sequence to the simulation to the test bench.
Todo
Reinvoke the simulator and run the simulation…can you see the value update now?
1.5. Simulation Improvement and Next feature¶
We should now have covered the minimal basics to quick off a digital design:
- Create a Module
- Create a testbench
- Add a clock generator and a reset sequence
- Get used to restarting the simulation
From here on, we will then add more features to the counter.
For each of the described features, you should:
- Implement it in the counter Module
- Drive the signal from the test bench to test it
- Make the testbench fail if the counter does not behave as expected
This assignment will be detailed as before, and the next features will just be described and left for you to implement.
1.5.1. Testbench preparation for unit testing¶
Now that we are adding more features, we could improve the test bench to make it “clever” and actively test the features.
To do so, it is easy to add display text for the command line output, and even error reporting.
For example, the actual test bench you have written so far just resets the counter, runs for a while then reaches $finish. You could improve the test bench to display some text, like you would in a normal C software.
For example:
initial
begin
...
...
$display("Finished...")
$finish();
end
Or in case of error:
initial
begin
...
// test the output of the DUT
if (tested_output == 0) begin
// Will stop simulation
$fatal("tested_output should be 1 here...");
end
...
$display("Finished...")
$finish();
end
Warning
$fatal is part of SystemVerilog, you should add the -sv to the command line when calling irun
Tip
Look at the System Verilog reference document
, Section 23 (System Tasks)
1.5.2. Enable¶
An enable signal is a control signal, which typically stops the activity.
You should:
- Add a new input to the counter, which stops the counter when 0, and resumes when 1
- Improve the testbench to test the sequence

Tip
Consult the lecture Simulation Synchronisation for simple examples on how to sycnhronise the testbench with the design.
Question
How/When did you change the enable signal in the testbench? Did it work correctly?
1.5.3. Reinit¶
A reinit signal is very similar to a reset and provides the same functionality.
However, resets are meant to bring a system to an initial state, and reinit signals to bring a certain module to a start state.
You should:
- Add a new input to reinitialise the counter
- Improve the test bench to test this signal

Tip
The Reinit should be similar to reset right now.
Tip
Use the reinit signal to reset the counter between features tests
1.5.4. Overflow¶
A classical counter device will offer an overflow output. Overflows are used for example in a processor system to be woken by interrupt after a certain time and perform an operation.
Typically, interrupt signals have to be cleared manually by the interrupt handler to avoid being triggered if the handler is slower than the interrupt generation rate.
You should:
- Add an overflow output, which toggles to 1 when the counter’s value comes back to 0
- Add a matching clear_overflow input, which resets the overflow value back to 0
- Add an overflow_error output
- If the counter overflows when overflow is still 1, overflow_error is set to 1, the counter stops
- If the counter enters overflow error, only asserting reinit can reset it

Todo
Implement the features and test them in the test bench
Todo
Write down the use cases of this overflow to make sure you don’t miss a test
Question
How many test cases do you need?
Question
Did you forget to test the error case?
1.6. Making Configurable¶
Our counter now has a few features, however, it is still 8 bit wide.
You may have noticed by now, that the counter could be more or less than 8bits and require no changes in the implementation of the control features.
Todo
Look at the lecture part about Paremeterizing and make the width of the counter configurable with a parameter
Tip
Constants assignments require variable size assignment, look in the lecture at: Constant to Variable Size Assignment
Todo
Update the features dependending on the counter width, like the overflow.
Todo
Update the testbench and Make sure the features still work. if the testbench was written correctly, it should fail on error.
1.7. Shift Register output¶
To finish this first round of feature implementation, we will add a second counting output, based on a shift register. To make the design more interesting, we will also make this second output run on a different clock.
You should then:
- Add a “clk_sr” to drive the shift register counter
- Add a “reset_sr” to reset the shift register counter
- An “enable_sr” input to enable/disable the shift register counter
- Add an output “value_sr” for the shift register output

Todo
Prepare the input/outputs then the pipeline stage for the shift register output.
The Shift Register Counter basic construction will be detailed during the lecture.
For now we can create a simple Johnson or Ring Counter , which is simply:
- A Shift Register
- The input of the first bit is the output of the last bit inverted

Todo
Find How to assign the value_sr output to itself to implement the Shift Register Behaviour
Tip
Look at the lecture part about value assignment to find a way to define the shift register
Todo
Update the testbench by adding appropriate clock, reset and enable for the shift register output
Tip
Don’t hesitate to make the clocks run at different speeds to better see the difference in the waveform
1.8. Short Conclusion¶
During this first assigment, we have learned how to:
- Create a module for a simple circuit
- Setup an associated testbench
- Defined basic reset and reinit signals
- Add some features and test them using the test bench
- Create a shift register
- Run a parts of the logic under separated clocks.
In the next assignment we will look at the Synthesis Process to create a real circuit representation of the counter.